<!--
 * @Author: wcx 1055127249@qq.com
 * @Date: 2024-12-27 12:29:44
 * @LastEditors: wcx 1055127249@qq.com
 * @LastEditTime: 2025-01-17 17:33:59
 * @FilePath: \my-project\src\views\commonBizTable\components\baseForm.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <el-form ref="form" v-bind="$attrs" :model="form">
    <el-form-item v-for="(item, i) in columns" v-bind="formItemsProps(item)">
      <template v-if="detail">
        <template v-if="item?.options?.length">{{ getvalue(item) }}</template>
        <template v-else>{{ form[item.prop] || '-' }}</template>
      </template>
      <template v-else-if="['cascader', 'select'].includes(item.type)">
        <component v-model="form[item.prop]" v-bind="componentProps(item)" @visible-change="e => visibleChange(e, item)"
          style="width: 100%;">
          <el-option v-if="item.type === 'select'" v-for="option in item.options" v-bind="option"></el-option>
        </component>
      </template>
      <template v-else-if="['radio', 'switch'].includes(item.type)">
        <component v-model="form[item.prop]" v-bind="componentProps(item)">
          <el-radio v-if="item.type === 'radio'" v-for="option in item.options" :label="option.value">{{ option.label }}</el-radio>
          <el-checkbox v-if="item.type === 'checkbox'" v-for="option in item.options" :label="option.value">{{ option.label }}</el-checkbox>
        </component>
      </template>
      <template v-else-if="['checkbox'].includes(item.type)">
        <component v-model="form[item.prop]" v-bind="componentProps(item)">
          <el-checkbox v-for="option in item.options" :label="option.value">{{ option.label }}</el-checkbox>
        </component>
      </template>
      <template v-else>
        <component v-model="form[item.prop]" v-bind="componentProps(item)" style="width: 100%;" />
      </template>
    </el-form-item>
    <el-form-item v-if="!hideSubmit">
      <template v-if="defaultSubmit">
        <el-button type="primary" @click="$emit('onSubmit', form)">提交</el-button>
        <el-button @click="resetForm">重置</el-button>
      </template>
      <slot name="button"></slot>
    </el-form-item>
    <slot></slot>
  </el-form>
</template>
<script>
import { deepCopy } from '@/utils'
import elFormItems from '@/utils/formUtils'
export default {
  props: {
    detail: {
      type: Boolean,
      default: false
    },
    validator: {
      type: Boolean,
      default: true
    },
    value: {
      type: Object,
      default: () => ({})
    },
    hideSubmit: {
      type: Boolean,
      default: false
    },
    defaultSubmit: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      form: {},
      columns: []
    }
  },
  watch: {
    form() {
      this.$emit('input', this.form)
    }
  },
  methods: {
    getvalue(data){
      const item = data.options.find(i => i.value === this.form[data.prop])
      return item?.label || '-'
    },
    setFileds(list) {
      let emptyData = {}
      if (this.value) {
        emptyData = deepCopy(this.value)
      }
      list.forEach(item => {
        if (item.type === 'checkbox' && !this.form[item.prop]) {
          emptyData[item.prop] = []
        }
      });
      this.form = { ...emptyData }
      this.columns = list
    },
    visibleChange(value, item) {
      if (item.visibleChange) {
        new Function('value', 'form', item.visibleChange).bind(this)(value)
      }
    },
    resetForm() {
      this.$refs.form.resetFields();
    },
    checkValidator(validator) {
      return async (rule, value, callback) => {
        const result = await new Function('value', 'form', validator).bind(this)(value, this.form)
        if (typeof result === 'boolean' && result) {
          callback()
        } else {
          callback(result || '输入不合法')
        }
      }
    },
    formItemsProps({ label, prop, required, validator }) {
      label += ' :'
      const rules = []
      const result = { label, prop }
      if (!this.validator) return result
      if (required) {
        rules.push({ required: true, message: '请输入' + label, trigger: 'blur' })
      }
      if (validator) {
        rules.push({ validator: this.checkValidator(validator), trigger: 'blur' })
      }
      if (rules.length) result.rules = rules
      return result
    },
    componentProps(item) {
      const elItem = elFormItems.find(i => i.value === item.type)
      let props = { ...elItem, ...item.props }
      if (!elItem) {
        props.is = item.type
      }
      if (item.type === 'cascader') {
        props.options = item.options
      }
      delete props.value
      return props
    },
  }
}
</script>